#include "VulkanFence.h"
#include "VulkanDevice.h"
namespace Alice
{
    VulkanFence::VulkanFence(VulkanDevice*inVulkanDevice,bool inbCreateSignaled)
        :mVulkanDevice(inVulkanDevice)
        ,mState(inbCreateSignaled?EState::Signaled:EState::NotReady)
    {
        VkFenceCreateInfo Info={};
        Info.sType=VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
        Info.flags = inbCreateSignaled ? VK_FENCE_CREATE_SIGNALED_BIT : 0;
        vkCreateFence(mVulkanDevice->GetDevice(), &Info, nullptr, &mFence);
    }
    VulkanFence::~VulkanFence()
    {
        
    }
    void VulkanFence::Reset()
    {
        vkResetFences(mVulkanDevice->GetDevice(),1,&mFence);
        mState = EState::NotReady;
    }

    FenceManager::FenceManager()
        :mDevice(nullptr)
    {
        
    }
    void FenceManager::Init(VulkanDevice* inDevice)
    {
        mDevice=inDevice;
    }

    VulkanFence* FenceManager::AllocateFence(bool bCreateSignaled)
    {
        /*if (FreeFences.Num() != 0)
        {
            FFence* Fence = FreeFences[0];
            FreeFences.RemoveAtSwap(0, EAllowShrinking::No);
            UsedFences.Add(Fence);

            if (bCreateSignaled)
            {
                Fence->State = FFence::EState::Signaled;
            }
            return Fence;
        }*/

        VulkanFence* NewFence = new VulkanFence(mDevice, bCreateSignaled);
        //UsedFences.Add(NewFence);
        return NewFence;
    }
    bool FenceManager::WaitForFence(VulkanFence* inFence, uint64 inTimeInNanoseconds) const
    {
        const VkResult result = vkWaitForFences(mDevice->GetDevice(), 1, &inFence->mFence, true, inTimeInNanoseconds);
        if(result==VK_SUCCESS)
        {
            inFence->mState=VulkanFence::EState::Signaled;
            return true;
        }
        return false;
    }
}